// 版权所有2009 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package math

const (
	uvnan    = 0x7FF8000000000001
	uvinf    = 0x7FF0000000000000
	uvneginf = 0xFFF0000000000000
	uvone    = 0x3FF0000000000000
	mask     = 0x7FF
	shift    = 64 - 11 - 1
	bias     = 1023
	signMask = 1 << 63
	fracMask = 1<<shift - 1
)

// Inf如果符号>=0则返回正无穷大，如果符号<0则返回负无穷大。
func Inf(sign int) float64 {
	var v uint64
	if sign >= 0 {
		v = uvinf
	} else {
		v = uvneginf
	}
	return Float64frombits(v)
}

// NaN返回一个IEEE 754“非数字”值。
func NaN() float64 { return Float64frombits(uvnan) }

// IsNaN报告f是否为IEEE 754“非数字”值。
func IsNaN(f float64) (is bool) {
	// IEEE754说只有NAN满足f！=f、 
	// 为了避免使用浮点硬件，可以使用：
	// x:=float64位（f）；
	// 返回uint32（x>>shift）和mask==mask&&x！=uvinf&&x！=uvneginf 
	return f != f
}

// IsInf根据符号报告f是否为无穷大。
// 如果符号大于0，IsInf将报告f是否为正无穷大。
// 如果符号<0，IsInf报告f是否为负无穷大。
// 如果符号=0，IsInf报告f是否为无穷大。
func IsInf(f float64, sign int) bool {
	// 通过与最大浮点数进行比较来测试无穷大。
	// 为了避免使用浮点硬件，可以使用：
	// x:=float64位（f）；
	// 返回符号>=0&&x==uvinf | |符号<=0&&x==uvneginf；
	return sign >= 0 && f > MaxFloat64 || sign <= 0 && f < -MaxFloat64
}

// normalize返回一个正态数y和指数exp 
// 满足x==y×2**exp。它假设x是有限的且非零。
func normalize(x float64) (y float64, exp int) {
	const SmallestNormal = 2.2250738585072014e-308 // 2**-1022 
	if Abs(x) < SmallestNormal {
		return x * (1 << 52), -52
	}
	return x, 0
}
